/**
 * 
 */
package org.jenkon.commons.collection.factory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * @author Jens Konopka
 * 
 */
public final class CollectionFactory {

	private static final int DEFAULT_INITIAL_CAPACITY = 256;

	/**
	 * 
	 */
	private CollectionFactory() {
	}

	/**
	 * Create a instance of the given {@link Collection} with the {@value #DEFAULT_INITIAL_CAPACITY} initial capacity.<br>
	 * Is the type a {@link SortedSet} then the {@link #DEFAULT_INITIAL_CAPACITY} was not used.
	 * 
	 * @param type Type of {@link Collection}
	 * @return the instantiated Collection by the given Type
	 * @see #createCollection(Class, int)
	 * @throws IllegalArgumentException Unsupported Collection interface or Unsupported Collection type
	 */
	public static <T> Collection<T> createCollection(final Class<?> type) {
		return createCollection(type, DEFAULT_INITIAL_CAPACITY);
	}

	/**
	 * @param type Type of {@link Collection}
	 * @param initialCapacity the initial capacity of the {@link Collection}
	 * @return the instantiated Collection by the given Type
	 * @throws IllegalArgumentException Unsupported Collection interface or Unsupported Collection type
	 */
	@SuppressWarnings("unchecked")
	public static <T> Collection<T> createCollection(final Class<?> type, final int initialCapacity) {

		if (type.isInterface()) {

			if (List.class.equals(type)) {
				return new ArrayList<T>(initialCapacity);
			} else if (SortedSet.class.equals(type)) {
				return new TreeSet<T>();
			} else if (Set.class.equals(type) || Collection.class.equals(type)) {
				return new LinkedHashSet<T>(initialCapacity);
			} else {
				throw new IllegalArgumentException("Unsupported Collection interface: " + type.getName());
			}

		} else {

			if (!Collection.class.isAssignableFrom(type)) {
				throw new IllegalArgumentException("Unsupported Collection type: " + type.getName());
			}

			try {
				return (Collection<T>) type.newInstance();
			} catch (final Exception e) {
				throw new IllegalArgumentException("Could not instantiate Collection type: " + type.getName(), e);
			}

		}

	}

}
